/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package compilador.analisadorSemantico;

import compilador.analisadorSintatico.simboloGramatical.ArvoreSintatica;
import compilador.analisadorSintatico.simboloGramatical.NaoTerminal;
import compilador.analisadorSintatico.simboloGramatical.SimboloGramatical;
import compilador.analisadorSintatico.simboloGramatical.Terminal;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Henrique
 */
public class AnalisadorSemantico {
    public static final boolean DEBUG = true;
    
    private ArvoreSintatica arvoreSintatica;
    private List<ErroSemantico> errosSemanticos;

    public AnalisadorSemantico() {
    }

    public List<ErroSemantico> getErrosSemanticos() {
        return errosSemanticos;
    }
    
    protected ArvoreSintatica getArvoreSintatica(){
        return arvoreSintatica;
    }

    public void analisar(ArvoreSintatica arvoreSintatica){
        this.arvoreSintatica = arvoreSintatica;
        this.errosSemanticos = new ArrayList<ErroSemantico>();

        GeradorTabela gerador = new GeradorTabela(this);
        gerador.preencheTabelaSimbolos();
        
        ChecadorTipos chec = new ChecadorTipos(this);
        chec.checar();
    }


    /*Métodos que serão utilizados pelas demais classes do analisado semantico
     */

    public static NaoTerminal procuraEscopo(NaoTerminal nt, NaoTerminal escopoAtual){
        String nome = nt.getNome();
        NaoTerminal escopo = escopoAtual;

        if(nome.equals("CLASSE")){
            escopo = nt;

        }else if(nome.equals("DEC_CLASSE_INTERNA")){
            escopo = nt;

        }else if(nome.equals("DEC_METODO")){
            escopo = nt;
        }

        return escopo;
    }
    
    public static int getNumeroLinha(NaoTerminal nt) {
        System.out.println("getNumeroLinha " + nt.getNome());
        
        //pesquisa número da linha
        int linha = -1;
        SimboloGramatical simb = nt;
        while (simb instanceof NaoTerminal) {
            NaoTerminal naoTerminal = (NaoTerminal) simb;
            
            if(naoTerminal.getFilhos().isEmpty())
                return -1;
            
            simb = naoTerminal.get(0);
            
        }
  
        if (simb instanceof Terminal) {
            linha = ((Terminal) simb).getSimbolo().getLinha();
        }
        
        return linha;
    }
    
    public static String extraiIdDeNomeOuTipoPrimitivo(NaoTerminal nomeNaoTerminal){
        String nome = null;
        
        if(nomeNaoTerminal.getNome().equals("NOME") || nomeNaoTerminal.getNome().equals("TIPO_PRIMITIVO")){
            Terminal identificadorTerminal = (Terminal) nomeNaoTerminal.get(0);
            nome = identificadorTerminal.getSimbolo().getAtributo().toString();   
        }
        
        return nome;
    }
    
    public static String extraiIdDeTipo(NaoTerminal tipoNaoTerminal){
        String nome = null;
        
        if(tipoNaoTerminal.getNome().equals("TIPO")){
            NaoTerminal nomeNaoTerminal = (NaoTerminal) tipoNaoTerminal.get(0);
            nome = extraiIdDeNomeOuTipoPrimitivo(nomeNaoTerminal);
        }
        
        return nome;
    }
    

}
